<?php
namespace plugins\HuaweiObs\controller;

use app\common\controller\Common;
use think\facade\Env;
use think\Db;

/**
 * 华为云obs上传控制器
 * @package plugins\Aliobs
 */
require Env::get('root_path').'plugins/HuaweiObs/SDK/obs-autoloader.php';
use Obs\ObsClient;

class HuaweiObs extends Common
{
    private $obsClient;

    private $config;

    protected function initialize()
    {

        $this->config = plugin_config('HuaweiObs');

        $error_msg = '';
        if ($this->config['key'] == '') {
            $error_msg = '未填写华为云OBS【AccessKey】';
        } elseif ($this->config['secret'] == '') {
            $error_msg = '未填写华为云OBS【SecretKey】';
        } elseif ($this->config['bucket'] == '') {
            $error_msg = '未填写华为云OBS桶名称';
        } elseif ($this->config['endpoint'] == '') {
            $error_msg = '未填写华为云OBS【Endpoint】';
        } elseif ($this->config['domain'] == '') {
            $error_msg = '未填写访问域名';
        }

        if ($error_msg != '') {
            return json([
                'code'   => 0,
                'class'  => 'danger',
                'info'   => $error_msg
            ]);
        }

        // 创建ObsClient实例
        $this->obsClient = new ObsClient([
            'key' => $this->config['key'],
            'secret' => $this->config['secret'],
            'endpoint' => rtrim($this->config['endpoint'], '/')
        ]);
    }

    /**
     * 直接上传到华为云obs
     */
    public function upload($file = [])
    {
        try{
            //文件名称(目标文件夹)
            $obs_dir = '';
            if(!empty($this->config['dir'])){
                $obs_dir = rtrim($this->config['dir'], '/') . '/';
            }
            $objectname = $obs_dir . $file['savepath'] . $file['savename'];

            $localfile = $file['tmp_name'];

            $this->obsClient->putObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $objectname,
                'SourceFile' => $localfile
            ]);

            $file['url'] = $objectname;
        } catch(\Exception $e) {
            return json(['code' => 0, 'class' => 'danger', 'info' => '服务器内部错误']);
        }
        return $file;
    }

    /**
     * obs 检查bucket是否存在
     * @param  string    $bucket    存储空间名称。
     * @return boolean ，true-是，false-否
     */
    public function isexistBucket($bucketname) {
        try{
            $resp = $this->obsClient->headBucket([
                'Bucket' => $bucketname
            ]);
        }catch (\Obs\Common\ObsException $obsException){
            if($obsException->getStatusCode() === 404){
                return false;
            }else{
                return true;
            }
        }
        return true;
    }

    /**
     * obs 创建bucket
     * @param $bucket 储存空间名称
     */
    public function createBucket($bucketname) {
        try{
            if(!$bucketname){
                throw new \Exception('缺少参数');
            }
            $this->obsClient->createBucket([
                'Bucket' => $bucketname
            ]);
        }catch (\Exception $e){
            return false;
        }
        return true;
    }

    /**
     * obs 下载到本地文件
     * @param  string    $object    表示您在下载文件时需要指定的文件名称，如abc/efg/123.jpg
     * @param  string    $localfile     指定文件下载路径。
     * @return boolean ，true-成功，false-失败
     */
    public function getObject($object, $localfile='') {
        try{
            if(!$object || !$localfile){
                throw new \Exception('缺少参数');
            }
            $l = strripos($localfile, '/');
            $savepath = substr($localfile,0, $l);
            if(!is_dir($savepath)){
                mkdir($savepath, 0777, true);
            }
            $this->obsClient->getObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $object,
                'SaveAsFile' => $localfile,
            ]);
        }catch (\Exception $e){
            return false;
        }
        return true;

    }

    /**
     * obs 删除单个文件
     * @param  string   $objectname    yourObjectName
     * @return boolean ，true-删除成功，false-删除失败
     */
    public function deleteObject($objectname){
        try{
            $this->obsClient->deleteObject ([
                'Bucket' => $this->config['bucket'],
                'Key' => $objectname
            ]);
        } catch(\Exception $e) {
            return json([
                'code'   => 0,
                'class'  => 'danger',
                'info'   => $e->getMessage()
            ]);
        }
        return true;
    }

    /**
     * obs 删除多个文件(批量删除)
     * @param  array    $objects    [yourObjectName1 yourObjectName2]
     * @return boolean ，true-删除成功，false-删除失败
     */
    public function deleteObjects($objectnames){
        try{
            $Objects = [];
            foreach ($objectnames as $key=>$objectname){
                $Objects[$key]['Key'] = $objectname;
                $Objects[$key]['VersionId'] = null;
            }
            $this->obsClient->deleteObjects ( [
                'Bucket' => $this->config['bucket'],
                'Quiet' => false,
                'Objects' => $Objects
            ] );
        } catch(\Exception $e) {
            return json([
                'code'   => 0,
                'class'  => 'danger',
                'info'   => $e->getMessage()
            ]);
        }
        return true;
    }

    /**
     * obs 拷贝文件
     * @param  $from_object    string
     * @param  $to_object    string
     * @return boolean ，true-删除成功，false-删除失败
     */
    public function copyObject($from_object, $to_object){
        try{
            $resp = $this->obsClient->copyObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $to_object,
                'CopySource' => $this->config['bucket'].'/'.$from_object
            ]);
        } catch(\Exception $e) {
            return false;
        }

        return true;
    }

    /**
     * 签名URL生成
     * @return boolean ，true-删除成功，false-删除失败
     */
    public function signedUrl(){

        $file_name = input('get.file_name/s');
        if(!$file_name){
            $file_name = 'wjl/'.uniqid();
        }

        // 生成上传对象的带授权信息的URL
        $params = [
            'Method' => 'PUT',
            'Bucket' => $this->config['bucket'],
            'Key' => $file_name,
            'Expires' => 3600,
        ];

        $type = input('get.type/s');
        if($type){
            $params['Headers'] = [ 'content-type' => $type, ];
        }

        try {
            $resp = $this->obsClient->createSignedUrl($params)->toArray();
        } catch ( Obs\Common\ObsException $obsException ) {
            jerror($obsException->getExceptionMessage ());
        }

        $resp['file_name'] = $file_name;
        return $resp;
    }

    /**
     * 签名URL生成
     * @return boolean ，true-删除成功，false-删除失败
     */
    public function postSignature(){

        $file_name = input('get.file_name/s');
        if(!$file_name){
            $file_name = 'wjl/'.uniqid();
        }

        // 生成上传对象的带授权信息的URL
        $params = [
            'Bucket' => $this->config['bucket'],
            'Key' => $file_name,
            'Expires' => 3600
        ];

        $type = input('get.type/s');
        if($type){
            $params['FormParams'] = [ 'content-type' => $type, ];
        }

        try {
            $resp = $this->obsClient->createPostSignature($params)->toArray();
        } catch ( Obs\Common\ObsException $obsException ) {
            jerror($obsException->getExceptionMessage ());
        }

        $resp['file_name'] = $file_name;
        $resp['domain'] = $this->config['domain'];
        $resp['accessKey'] = $this->config['accessKey'];

        return $resp;
    }

}